package com.abel.bigwater.dataserver.model.qdies

import com.abel.bigwater.data.BcdString
import com.alibaba.fastjson.JSON
import io.netty.buffer.Unpooled
import org.joda.time.DateTime
import org.junit.Assert.*
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runners.MethodSorters
import org.slf4j.LoggerFactory
import java.net.InetAddress
import java.net.InetSocketAddress
import java.util.*

@FixMethodOrder(MethodSorters.DEFAULT)
class D10PacketTest {

    @Test
    fun fillLogin() {
        val buf = Unpooled.buffer()
        val p = D10Packet().apply {
            address = BcdString(byteArrayOf(12, 0, 0, 1), true)
            func = FuncType.Login
            data = D10LoginData().also {
                it.address = address
            }

            fill(buf)
        }

        val str = BcdString.create(buf, buf.readableBytes()).bcdString
        lgr.info(str)
        assertEquals(DEMO_LOGIN, str)
    }

    @Test
    fun parseLogin() {
        val buf = Unpooled.buffer().also { it.writeBytes(BcdString.toByteArray(DEMO_LOGIN)) }
        val p = D10Packet()
        assertTrue(p.parse(buf))

        lgr.info(JSON.toJSONString(p, true))
        assertEquals(FuncType.Login, p.data?.type)
    }

    @Test
    fun fillHeart() {
        val buf = Unpooled.buffer()
        val p = D10Packet().apply {
            address = BcdString(byteArrayOf(12, 0, 0, 1), true)
            func = FuncType.Heart
            data = D10HeartData().also {
                it.address = address
            }

            fill(buf)
        }

        val str = BcdString.create(buf, buf.readableBytes()).bcdString
        lgr.info(str)
        assertEquals(DEMO_HEART, str)
    }

    @Test
    fun parseHeart() {
        val buf = Unpooled.buffer().also { it.writeBytes(BcdString.toByteArray(DEMO_HEART)) }
        val p = D10Packet()
        assertTrue(p.parse(buf))

        lgr.info(JSON.toJSONString(p, true))
        assertEquals(FuncType.Heart, p.data?.type)
    }

    @Test
    fun fillSetTime() {
        val buf = Unpooled.buffer()
        val p = D10Packet().apply {
            address = BcdString(byteArrayOf(12, 0, 0, 1), true)
            func = FuncType.SetTime
            data = DtenSetTimeData(-1)

            fill(buf)
        }

        val str = BcdString.create(buf, buf.readableBytes()).bcdString
        lgr.info(str)
        assertEquals(DEMO_SET_TIME, str)
    }

    @Test
    fun parseSetTime() {
        val buf = Unpooled.buffer().also { it.writeBytes(BcdString.toByteArray(DEMO_SET_TIME)) }
        val p = D10Packet()
        assertTrue(p.parse(buf))

        lgr.info(JSON.toJSONString(p, true))
        assertEquals(FuncType.SetTime, p.data?.type)
    }

    @Test
    fun fillAskTime() {
        val buf = Unpooled.buffer()
        val p = D10Packet().apply {
            address = BcdString(byteArrayOf(12, 0, 0, 1), true)
            func = FuncType.AskTime
            data = DtenAskTimeData(-1).also {
                it.time = DateTime(2012, 10, 31, 11, 15, 20).toDate()
            }

            fill(buf)
        }

        val str = BcdString.create(buf, buf.readableBytes()).bcdString
        lgr.info(str)
        assertEquals(DEMO_ASK_TIME, str)
    }

    @Test
    fun parseAskTime() {
        val buf = Unpooled.buffer().also { it.writeBytes(BcdString.toByteArray(DEMO_ASK_TIME)) }
        val p = D10Packet()
        assertTrue(p.parse(buf))

        lgr.info(JSON.toJSONString(p, true))
        assertEquals(FuncType.AskTime, p.data?.type)
        assertTrue(p.data is DtenAskTimeData)
        assertEquals(DateTime(2012, 10, 31, 11, 15, 20).toDate(), (p.data as DtenAskTimeData).time)
    }

    @Test
    fun fillSetIpPort() {
        val buf = Unpooled.buffer()
        val p = D10Packet().apply {
            address = BcdString(byteArrayOf(12, 0, 0, 1), true)
            func = FuncType.SetIpPort
            data = DtenSetIpPortData(-1)

            fill(buf)
        }

        val str = BcdString.create(buf, buf.readableBytes()).bcdString
        lgr.info(str)
        assertEquals(DEMO_SET_IP_PORT, str)
    }

    @Test
    fun parseSetIpPort() {
        val buf = Unpooled.buffer().also { it.writeBytes(BcdString.toByteArray(DEMO_SET_IP_PORT)) }
        val p = D10Packet()
        assertTrue(p.parse(buf))

        lgr.info(JSON.toJSONString(p, true))
        assertEquals(FuncType.SetIpPort, p.data?.type)
    }

    @Test
    fun fillAskIpPort() {
        val buf = Unpooled.buffer()
        val p = D10Packet().apply {
            address = BcdString(byteArrayOf(12, 0, 0, 1), true)
            func = FuncType.AskIpPort
            data = DtenAskIpPortData(-1).also {
                it.address = InetSocketAddress(InetAddress.getByAddress(byteArrayOf(0xC0.toByte(), 0xA8.toByte(),
                        0x01, 0x0F)), 0x1389)
            }

            fill(buf)
        }

        val str = BcdString.create(buf, buf.readableBytes()).bcdString
        lgr.info(str)
        assertEquals(DEMO_ASK_IP_PORT, str)
    }

    @Test
    fun parseAskIpPort() {
        val buf = Unpooled.buffer().also { it.writeBytes(BcdString.toByteArray(DEMO_ASK_IP_PORT)) }
        val p = D10Packet()
        assertTrue(p.parse(buf))

        lgr.info(JSON.toJSONString(p, true))
        assertEquals(FuncType.AskIpPort, p.data?.type)
        assertTrue(p.data is DtenAskIpPortData)
        assertEquals(InetSocketAddress(InetAddress.getByAddress(byteArrayOf(0xC0.toByte(), 0xA8.toByte(),
                0x01, 0x0F)), 0x1389),
                (p.data as DtenAskIpPortData).address)
    }

    @Test
    fun fillSetPulseBase() {
        val buf = Unpooled.buffer()
        val p = D10Packet().apply {
            address = BcdString(byteArrayOf(12, 0, 0, 1), true)
            func = FuncType.SetPulseBase
            data = DtenPulseBaseData(-1).also {
                it.internalAddress = 0x0B
            }

            fill(buf)
        }

        val str = BcdString.create(buf, buf.readableBytes()).bcdString
        lgr.info(str)
        assertEquals(DEMO_SET_PULSE_BASE, str)
    }

    @Test
    fun parseSetPulseBase() {
        val buf = Unpooled.buffer().also { it.writeBytes(BcdString.toByteArray(DEMO_SET_PULSE_BASE)) }
        val p = D10Packet()
        assertTrue(p.parse(buf))

        lgr.info(JSON.toJSONString(p, true))
        assertEquals(FuncType.SetPulseBase, p.data?.type)
        assertTrue(p.data is DtenPulseBaseData)
        assertEquals(11.toByte(), (p.data as DtenPulseBaseData).internalAddress)
    }

    @Test
    fun fillSetActiveOnline() {
        val buf = Unpooled.buffer()
        val p = D10Packet().apply {
            address = BcdString(byteArrayOf(12, 0, 0, 1), true)
            func = FuncType.SetActiveOnline
            data = DtenSetActiveOnlineData(-1)

            fill(buf)
        }

        val str = BcdString.create(buf, buf.readableBytes()).bcdString
        lgr.info(str)
        assertEquals(DEMO_SET_ACTIVE_ONLINE, str)
    }

    @Test
    fun parseSetActiveOnline() {
        val buf = Unpooled.buffer().also { it.writeBytes(BcdString.toByteArray(DEMO_SET_ACTIVE_ONLINE)) }
        val p = D10Packet()
        assertTrue(p.parse(buf))

        lgr.info(JSON.toJSONString(p, true))
        assertEquals(FuncType.SetActiveOnline, p.data?.type)
        assertTrue(p.data is DtenSetActiveOnlineData)
    }

    @Test
    fun fillAskActiveOnline() {
        val buf = Unpooled.buffer()
        val p = D10Packet().apply {
            address = BcdString(byteArrayOf(12, 0, 0, 1), true)
            func = FuncType.AskActiveOnline
            data = DtenAskActiveOnlineData(-1).also {
                it.hourList = byteArrayOf(0x0A, 0x0F)
            }

            fill(buf)
        }

        val str = BcdString.create(buf, buf.readableBytes()).bcdString
        lgr.info(str)
        assertEquals(DEMO_ASK_ACTIVE_ONLINE, str)
    }

    @Test
    fun parseAskActiveOnline() {
        val buf = Unpooled.buffer().also { it.writeBytes(BcdString.toByteArray(DEMO_ASK_ACTIVE_ONLINE)) }
        val p = D10Packet()
        assertTrue(p.parse(buf))

        lgr.info(JSON.toJSONString(p, true))
        assertEquals(FuncType.AskActiveOnline, p.data?.type)
        assertTrue(p.data is DtenAskActiveOnlineData)
        assertArrayEquals(byteArrayOf(0x0A, 0x0F), (p.data as DtenAskActiveOnlineData).hourList)
    }

    @Test
    fun fillSetUploadMode() {
        val buf = Unpooled.buffer()
        val p = D10Packet().apply {
            address = BcdString(byteArrayOf(12, 0, 0, 1), true)
            func = FuncType.SetUploadMode
            data = DtenSetUploadModeData()

            fill(buf)
        }

        val str = BcdString.create(buf, buf.readableBytes()).bcdString
        lgr.info(str)
        assertEquals(DEMO_SET_UPLOAD_MODE, str)
    }

    @Test
    fun parseSetUploadMode() {
        val buf = Unpooled.buffer().also { it.writeBytes(BcdString.toByteArray(DEMO_SET_UPLOAD_MODE)) }
        val p = D10Packet()
        assertTrue(p.parse(buf))

        lgr.info(JSON.toJSONString(p, true))
        assertEquals(FuncType.SetUploadMode, p.data?.type)
        assertTrue(p.data is DtenSetUploadModeData)
    }

    @Test
    fun fillAskUploadMode() {
        val buf = Unpooled.buffer()
        val p = D10Packet().apply {
            address = BcdString(byteArrayOf(12, 0, 0, 1), true)
            func = FuncType.AskUploadMode
            data = DtenAskUploadModeData(-1).also {
                it.uploadMode = UploadModeType.GPRS
            }

            fill(buf)
        }

        val str = BcdString.create(buf, buf.readableBytes()).bcdString
        lgr.info(str)
        assertEquals(DEMO_ASK_UPLOAD_MODE, str)
    }

    @Test
    fun parseAskUploadMode() {
        val buf = Unpooled.buffer().also { it.writeBytes(BcdString.toByteArray(DEMO_ASK_UPLOAD_MODE)) }
        val p = D10Packet()
        assertTrue(p.parse(buf))

        lgr.info(JSON.toJSONString(p, true))
        assertEquals(FuncType.AskUploadMode, p.data?.type)
        assertTrue(p.data is DtenAskUploadModeData)
        assertEquals(UploadModeType.GPRS, (p.data as DtenAskUploadModeData).uploadMode)
    }

    @Test
    fun fillAsk485Hist() {
        val buf = Unpooled.buffer()
        val p = D10Packet().apply {
            address = BcdString(byteArrayOf(12, 0, 0, 1), true)
            func = FuncType.Ask485Hist
            data = DtenAsk485HistData(-1).also {
                it.internalAddr = 1
                it.lastReadTimeBcd = BcdString(byteArrayOf(0x12, 0x10, 0x25, 0x15, 0), true)
                it.readGood = BitSet.valueOf(byteArrayOf(0x0F, 0xFF.toByte()))
                it.readList = floatArrayOf(100010F, 100020F, 100030F, 100040F, 100050F, 100060F,
                        100070F, 100080F, 100090F, 100100F, 100110F, 100120F,
                        100130F, 100140F)
            }

            fill(buf)
        }

        val str = BcdString.create(buf, buf.readableBytes()).bcdString
        lgr.info(str)
        assertEquals(DEMO_ASK_485_HIST, str)
    }

    @Test
    fun parseAsk485Hist() {
        val buf = Unpooled.buffer().also { it.writeBytes(BcdString.toByteArray(DEMO_ASK_485_HIST)) }
        val p = D10Packet()
        assertTrue(p.parse(buf))

        lgr.info(JSON.toJSONString(p, true))
        assertEquals(FuncType.Ask485Hist, p.data?.type)
        assertTrue(p.data is DtenAsk485HistData)

        val data = p.data as DtenAsk485HistData
        assertEquals(0x01.toByte(), data.internalAddr)
        assertEquals(ReadModeType.DayMode, data.readMode)
        assertEquals(DateTime(2012, 10, 25, 15, 0).toDate(), data.lastReadTime)
        assertArrayEquals(byteArrayOf(0x0F, 0xFF.toByte()), data.readGood.toByteArray())
        assertArrayEquals(floatArrayOf(100010F, 100020F, 100030F, 100040F, 100050F, 100060F,
                100070F, 100080F, 100090F, 100100F, 100110F, 100120F,
                100130F, 100140F).toTypedArray(),
                data.readList!!.toTypedArray())
    }

    @Test
    fun fillAskAnalogHist() {
        val buf = Unpooled.buffer()
        val p = D10Packet().apply {
            address = BcdString(byteArrayOf(12, 0, 0, 1), true)
            func = FuncType.AskAnalogHist
            data = DtenAskAnalogHistData(-1).also {
                it.internalAddr = 8
                it.lastReadTimeBcd = BcdString(byteArrayOf(0x12, 0x10, 0x17, 0x15, 0), true)
                it.readMode = ReadModeType.DayMode
                it.readGood = BitSet.valueOf(byteArrayOf(0x0F, 0xFF.toByte()))
                it.readList = floatArrayOf(320F, 309F, 315F, 312F, 322F, 313F)
            }

            fill(buf)
        }

        val str = BcdString.create(buf, buf.readableBytes()).bcdString
        lgr.info(str)
        assertEquals(DEMO_ASK_ANALOG_HIST, str)
    }

    @Test
    fun parseAskAnalogHist() {
        val buf = Unpooled.buffer().also { it.writeBytes(BcdString.toByteArray(DEMO_ASK_ANALOG_HIST)) }
        val p = D10Packet()
        assertTrue(p.parse(buf))

        lgr.info(JSON.toJSONString(p, true))
        assertEquals(FuncType.AskAnalogHist, p.data?.type)
        assertTrue(p.data is DtenAskAnalogHistData)

        val data = p.data as DtenAskAnalogHistData
        assertEquals(0x08.toByte(), data.internalAddr)
        assertEquals(ReadModeType.DayMode, data.readMode)
        assertEquals(DateTime(2012, 10, 17, 0, 0).toDate(), data.lastReadTime)
        assertArrayEquals(byteArrayOf(0x0F, 0xFF.toByte()), data.readGood.toByteArray())
        assertArrayEquals(floatArrayOf(320F, 309F, 315F, 312F, 322F, 313F).toTypedArray(),
                data.readList!!.toTypedArray())
    }

    @Test
    fun fillAskPulseHist() {
        val buf = Unpooled.buffer()
        val p = D10Packet().apply {
            address = BcdString(byteArrayOf(12, 0, 0, 1), true)
            func = FuncType.AskPulseHist
            data = DtenAskPulseHistData(-1).also {
                it.internalAddr = 11
                it.lastReadTimeBcd = BcdString(byteArrayOf(0x12, 0x10, 0x17, 0x15, 0x0), true)
                it.readMode = ReadModeType.WeekMode
                it.readGood = BitSet.valueOf(byteArrayOf(0x0F, 0xFF.toByte()))
                it.readList = floatArrayOf(100832F, 100810F, 100792F, 100778F, 100751F, 100726F, 100695F)
            }

            fill(buf)
        }

        val str = BcdString.create(buf, buf.readableBytes()).bcdString
        lgr.info(str)
        assertEquals(DEMO_ASK_PULSE_HIST, str)
    }

    @Test
    fun parseAskPulseHist() {
        val buf = Unpooled.buffer().also { it.writeBytes(BcdString.toByteArray(DEMO_ASK_PULSE_HIST)) }
        val p = D10Packet()
        assertTrue(p.parse(buf))

        lgr.info(JSON.toJSONString(p, true))
        assertEquals(FuncType.AskPulseHist, p.data?.type)
        assertTrue(p.data is DtenAskPulseHistData)

        val data = p.data as DtenAskPulseHistData
        assertEquals(0x0B.toByte(), data.internalAddr)
        assertEquals(ReadModeType.WeekMode, data.readMode)
        assertEquals(DateTime(2012, 10, 17, 0, 0).toDate(), data.lastReadTime)
        assertArrayEquals(byteArrayOf(0x0F, 0xFF.toByte()), data.readGood.toByteArray())
        assertArrayEquals(floatArrayOf(100832F, 100810F, 100792F, 100778F, 100751F, 100726F, 100695F).toTypedArray(),
                data.readList!!.toTypedArray())
    }

    @Test
    fun fillAskMeterConfig() {
        val buf = Unpooled.buffer()
        val p = D10Packet().apply {
            address = BcdString(byteArrayOf(12, 0, 0, 1), true)
            func = FuncType.AskMeterConfig
            data = DtenAskMeterConfigData(-1).also {
                it.addr485 = 1
                it.addrAnalog = 8
                it.addrPulse = 11
                it.addrExt = 0
            }

            fill(buf)
        }

        val str = BcdString.create(buf, buf.readableBytes()).bcdString
        lgr.info(str)
        assertEquals(DEMO_ASK_METER_CONFIG, str)
    }

    @Test
    fun parseAskMeterConfig() {
        val buf = Unpooled.buffer().also { it.writeBytes(BcdString.toByteArray(DEMO_ASK_METER_CONFIG)) }
        val p = D10Packet()
        assertTrue(p.parse(buf))

        lgr.info(JSON.toJSONString(p, true))
        assertEquals(FuncType.AskMeterConfig, p.data?.type)
        assertTrue(p.data is DtenAskMeterConfigData)

        val data = p.data as DtenAskMeterConfigData
        assertEquals(0x01.toByte(), data.addr485)
        assertEquals(0x08.toByte(), data.addrAnalog)
        assertEquals(0x0B.toByte(), data.addrPulse)
        assertEquals(0x00.toByte(), data.addrExt)
    }

    @Test
    fun fillAsk485Config() {
        val buf = Unpooled.buffer()
        val p = D10Packet().apply {
            address = BcdString(byteArrayOf(12, 0, 0, 1), true)
            func = FuncType.Ask485Config
            data = DtenAsk485ConfigData(-1).also {
                it.internalAddr = 1
                it.addr485 = 25
                it.baud = BaudRateType.Baud9600

                it.readMode = ReadModeType.WeekMode
                it.uploadStart = BcdString(byteArrayOf(2, 8), true)
                it.samplePeriod = 0
                it.uploadPeriod = 0
                it.volt = 0x0C
            }

            fill(buf)
        }

        val str = BcdString.create(buf, buf.readableBytes()).bcdString
        lgr.info(str)
        assertEquals(DEMO_CONFIG_485, str)
    }

    @Test
    fun parseAsk485Config() {
        val buf = Unpooled.buffer().also { it.writeBytes(BcdString.toByteArray(DEMO_CONFIG_485)) }
        val p = D10Packet()
        assertTrue(p.parse(buf))

        lgr.info(JSON.toJSONString(p, true))
        assertEquals(FuncType.Ask485Config, p.data?.type)
        assertTrue(p.data is DtenAsk485ConfigData)

        val data = p.data as DtenAsk485ConfigData
        assertEquals(0x01.toByte(), data.internalAddr)
        assertEquals(ReadModeType.WeekMode, data.readMode)
        assertArrayEquals(byteArrayOf(2, 8), data.uploadStart?.hexArray)
        assertEquals(0, data.samplePeriod)
        assertEquals(0.toShort(), data.uploadPeriod)
    }

    @Test
    fun fillAskAnalogConfig() {
        val buf = Unpooled.buffer()
        val p = D10Packet().apply {
            address = BcdString(byteArrayOf(12, 0, 0, 1), true)
            func = FuncType.AskAnalogConfig
            data = DtenAskAnalogConfigData(-1).also {
                it.internalAddr = 11
                it.rangeHigh = 2000F
                it.rangeLow = 0F
                it.warnHigh = 1600F
                it.warnLow = 0F

                it.readMode = ReadModeType.DayMode
                it.uploadStart = BcdString(byteArrayOf(0, 7), true)
                it.samplePeriod = 0
                it.uploadPeriod = 0

                it.volt = 12
            }

            fill(buf)
        }

        val str = BcdString.create(buf, buf.readableBytes()).bcdString
        lgr.info(str)
        assertEquals(DEMO_CONFIG_ANALOG, str)
    }

    @Test
    fun parseAskAnalogConfig() {
        val buf = Unpooled.buffer().also { it.writeBytes(BcdString.toByteArray(DEMO_CONFIG_ANALOG)) }
        val p = D10Packet()
        assertTrue(p.parse(buf))

        lgr.info(JSON.toJSONString(p, true))
        assertEquals(FuncType.AskAnalogConfig, p.data?.type)
        assertTrue(p.data is DtenAskAnalogConfigData)

        val data = p.data as DtenAskAnalogConfigData
        assertEquals(0x0B.toByte(), data.internalAddr)
        assertEquals(2000F, data.rangeHigh)
        assertEquals(1600F, data.warnHigh)

        assertEquals(ReadModeType.DayMode, data.readMode)
        assertArrayEquals(byteArrayOf(0, 7), data.uploadStart!!.bcdArray)
        assertEquals(0, data.samplePeriod)
        assertEquals(0.toShort(), data.uploadPeriod)
    }

    @Test
    fun fillAskPulseConfig() {
        val buf = Unpooled.buffer()
        val p = D10Packet().apply {
            address = BcdString(byteArrayOf(12, 0, 0, 1), true)
            func = FuncType.AskPulseConfig
            data = DtenAskPulseConfigData(-1).also {
                it.internalAddr = 11
                it.readMode = ReadModeType.DayMode
                it.uploadStart = BcdString(byteArrayOf(3, 15), true)
                it.samplePeriod = 120
                it.uploadPeriod = 3
            }

            fill(buf)
        }

        val str = BcdString.create(buf, buf.readableBytes()).bcdString
        lgr.info(str)
        assertEquals(DEMO_CONFIG_PULSE, str)
    }

    @Test
    fun parseAskPulseConfig() {
        val buf = Unpooled.buffer().also { it.writeBytes(BcdString.toByteArray(DEMO_CONFIG_PULSE)) }
        val p = D10Packet()
        assertTrue(p.parse(buf))

        lgr.info(JSON.toJSONString(p, true))
        assertEquals(FuncType.AskPulseConfig, p.data?.type)
        assertTrue(p.data is DtenAskPulseConfigData)

        val data = p.data as DtenAskPulseConfigData
        assertEquals(0x0B.toByte(), data.internalAddr)
        assertEquals(ReadModeType.DayMode, data.readMode)
        assertArrayEquals(byteArrayOf(3, 15), data.uploadStart!!.bcdArray)
        assertEquals(120, data.samplePeriod)
        assertEquals(3.toShort(), data.uploadPeriod)
    }

    @Test
    fun fillAsk485Now() {
        val buf = Unpooled.buffer()
        val p = D10Packet().apply {
            address = BcdString(byteArrayOf(12, 0, 0, 1), true)
            func = FuncType.Ask485Now
            data = DtenAsk485NowData(-1).also {
                it.internalAddr = 1
                it.sampleTimeBcd = BcdString(byteArrayOf(12, 10, 25, 15, 25), true)
                it.reading = 100283F
                it.status = 0
            }

            fill(buf)
        }

        val str = BcdString.create(buf, buf.readableBytes()).bcdString
        lgr.info(str)
        assertEquals(DEMO_ASK_485_NOW, str)
    }

    @Test
    fun parseAsk485Now() {
        val buf = Unpooled.buffer().also { it.writeBytes(BcdString.toByteArray(DEMO_ASK_485_NOW)) }
        val p = D10Packet()
        assertTrue(p.parse(buf))

        lgr.info(JSON.toJSONString(p, true))
        assertEquals(FuncType.Ask485Now, p.data?.type)
        assertTrue(p.data is DtenAsk485NowData)

        val data = p.data as DtenAsk485NowData
        assertEquals(0x01.toByte(), data.internalAddr)
        assertEquals(100283F, data.reading)
        assertArrayEquals(byteArrayOf(12, 10, 25, 15, 25), data.sampleTimeBcd!!.bcdArray)
    }

    @Test
    fun fillAskAnalogNow() {
        val buf = Unpooled.buffer()
        val p = D10Packet().apply {
            address = BcdString(byteArrayOf(12, 0, 0, 1), true)
            func = FuncType.AskAnalogNow
            data = DtenAskAnalogNowData().also {
                it.internalAddr = 8
                it.sampleTimeBcd = BcdString(byteArrayOf(12, 10, 25, 15, 25), true)
                it.reading = 320F
            }

            fill(buf)
        }

        val str = BcdString.create(buf, buf.readableBytes()).bcdString
        lgr.info(str)
        assertEquals(DEMO_ASK_ANALOG_NOW, str)
    }

    @Test
    fun parseAskAnalogNow() {
        val buf = Unpooled.buffer().also { it.writeBytes(BcdString.toByteArray(DEMO_ASK_ANALOG_NOW)) }
        val p = D10Packet()
        assertTrue(p.parse(buf))

        lgr.info(JSON.toJSONString(p, true))
        assertEquals(FuncType.AskAnalogNow, p.data?.type)
        assertTrue(p.data is DtenAskAnalogNowData)

        val data = p.data as DtenAskAnalogNowData
        assertEquals(0x08.toByte(), data.internalAddr)
        assertEquals(320F, data.reading)
        assertArrayEquals(byteArrayOf(12, 10, 25, 15, 25), data.sampleTimeBcd!!.bcdArray)
    }

    @Test
    fun fillAskPulseNow() {
        val buf = Unpooled.buffer()
        val p = D10Packet().apply {
            address = BcdString(byteArrayOf(12, 0, 0, 1), true)
            func = FuncType.AskPulseNow
            data = DtenAskPulseNowData().also {
                it.internalAddr = 12
                it.sampleTimeBcd = BcdString(byteArrayOf(12, 10, 25, 15, 25), true)
                it.reading = 128135F
            }

            fill(buf)
        }

        val str = BcdString.create(buf, buf.readableBytes()).bcdString
        lgr.info(str)
        assertEquals(DEMO_ASK_PULSE_NOW, str)
    }

    @Test
    fun parseAskPulseNow() {
        val buf = Unpooled.buffer().also { it.writeBytes(BcdString.toByteArray(DEMO_ASK_PULSE_NOW)) }
        val p = D10Packet()
        assertTrue(p.parse(buf))

        lgr.info(JSON.toJSONString(p, true))
        assertEquals(FuncType.AskPulseNow, p.data?.type)
        assertTrue(p.data is DtenAskPulseNowData)

        val data = p.data as DtenAskPulseNowData
        assertEquals(0x0C.toByte(), data.internalAddr)
        assertEquals(128135F, data.reading)
        assertArrayEquals(byteArrayOf(12, 10, 25, 15, 25), data.sampleTimeBcd!!.bcdArray)
    }


    companion object {
        private val lgr = LoggerFactory.getLogger(D10PacketTest::class.java)
        const val DEMO_LOGIN = "6812000001240a49455344313012000001be16"

        const val DEMO_HEART = "6812000001250a49455344313012000001bd16"

        const val DEMO_SET_TIME = "68120000010101aad916"

        const val DEMO_ASK_TIME = "6812000001020712103111152003e016"

        const val DEMO_SET_IP_PORT = "68120000010601007e16"

        const val DEMO_ASK_IP_PORT = "68120000010706c0a8010f13896416"

        const val DEMO_SET_PULSE_BASE = "68120000012c020baaa216"

        const val DEMO_SET_ACTIVE_ONLINE = "681200000138004d16"

        const val DEMO_ASK_ACTIVE_ONLINE = "68120000013903020a0f2e16"

        const val DEMO_SET_UPLOAD_MODE = "681200000127005e16"

        const val DEMO_ASK_UPLOAD_MODE = "68120000013701024b16"

        const val DEMO_ASK_485_HIST = "68120000011b40010112102515000fff0055c347005ac347005fc3470064c3470069c347006ec3470073c3470078c347007dc3470082c3470087c347008cc3470091c3470096c347c516"

        const val DEMO_ASK_ANALOG_HIST = "68120000011c20080112101715000fff0000a04300809a4300809d4300009c430000a14300809c432216"

        const val DEMO_ASK_PULSE_HIST = "68120000011d260b020f12101715000b0200f0c4470b0200e5c4470b0200dcc4470b0200d5c4470b0280c7c4470b0200bbc4470b0280abc4477d16"

        const val DEMO_ASK_METER_CONFIG = "6812000001110401080b005c16"

        const val DEMO_CONFIG_485 = "6812000001131501000000000000001901030101030202080000000c2216"

        const val DEMO_CONFIG_ANALOG = "681200000115190b0144fa00000000000044c80000000000000100070000000ced16"

        const val DEMO_CONFIG_PULSE = "681200000117070b010315007803c816"

        const val DEMO_ASK_485_NOW = "6812000001180eaa1210251525010147c3dd800000cb16"

        const val DEMO_ASK_ANALOG_NOW = "6812000001190caa1210251525080143a000004916"

        const val DEMO_ASK_PULSE_NOW = "68120000011a0caa12102515250c0147fa43802316"
    }
}